package com.xinjixian.webgame;

import android.app.Activity;
import android.app.ActivityManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.Window;


import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.security.cert.Certificate;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

import static androidx.core.content.FileProvider.getUriForFile;


/**
 * 有关APP的信息包括版本号，版本名，签名，安装路径等
 *
 * @author Phoenix
 * @date 2016-8-3 14:57
 */
public class APPUtil {



    private APPUtil() {
    }




    /**
     * 获取app应用包名
     *
     * @param context 上下文信息
     * @return 包名
     */
    public static String getPackageName(Context context) {
        if (context == null) {
            throw new IllegalArgumentException("Should not be null");
        }
        return context.getPackageName();
    }

    /**
     * @param context 上下文信息
     * @return 获取包信息
     */
    public static PackageInfo getPackageInfo(Context context) {
        PackageManager packageManager = context.getPackageManager();
        /** getPackageName()是当前类的包名，0代表获取版本信息 */
        try {
            return packageManager.getPackageInfo(context.getPackageName(), 0);
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }

        return null;
    }


    /**
     * 判断应用是否已经启动
     *
     * @param context 一个context
     * @return boolean
     */
    public static boolean isAppAlive(Context context) {
        ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        List<ActivityManager.RunningAppProcessInfo> processInfos = activityManager.getRunningAppProcesses();
        for (int i = 0; i < processInfos.size(); i++) {
            if (processInfos.get(i).processName.equals(getPackageName(context))) {
                return true;
            }
        }
        return false;
    }

    /**
     * 获取应用版本号
     *
     * @param context
     * @return 成功返回版本号，失败返回-1
     */
    public static int getVersionCode(Context context) {
        if (getPackageInfo(context) != null) {
            return getPackageInfo(context).versionCode;
        }

        return -1;
    }

    public static String getGameState(Context context, String gameName, String apkName) {
        List<String> apkNames = null;
        apkNames = StorageApkUtil.getFileName();
        boolean flag = false;   //是否本地已经有安装包
        for (int i = 0; i < apkNames.size(); i++) {
            if (gameName.equals(apkNames.get(i))) {
                flag = true;
            }
        }
        //判断游戏是否已经安装
        boolean isInstalled = APPUtil.isAPPInstalled(context, apkName);
        if (isInstalled) {
            return "启动";
        }
        if (flag && !isInstalled) {
            //LogUtils.e("dsdsdsdsd111111安装");
            return "安装";
        }
        return "下载";
    }

    /**
     * 获取应用版本名
     *
     * @param context
     * @return 成功返回版本名， 失败返回null
     */
    public static String getVersionName(Context context) {
        if (getPackageInfo(context) != null) {
            return getPackageInfo(context).versionName;
        }

        return null;
    }

    /**
     * 根据包名判断有无安装app
     */
    public static boolean isAPPInstalled(Context context, String appName) {
        final PackageManager packageManager = context.getPackageManager();
        List<PackageInfo> pinfo = packageManager.getInstalledPackages(0);
        if (pinfo != null) {
            for (int i = 0; i < pinfo.size(); i++) {
                String pn = pinfo.get(i).packageName;
                if (pn.equalsIgnoreCase(appName)) {
                    return true;
                }
            }
        }
        return false;
    }

    public static boolean isApkFileExit(String path) {
        File file = new File(path);
        return file.exists();
    }


    /**
     * 获取APP名称
     *
     * @param context
     * @return
     */
    public static String getAppName(Context context) {
        try {
            PackageManager packageManager = context.getPackageManager();
            PackageInfo packageInfo = packageManager.getPackageInfo(context.getPackageName(), 0);
            int labelRes = packageInfo.applicationInfo.labelRes;
            return context.getResources().getString(labelRes);
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 打开指定包名的APP
     *
     * @param context
     * @param packageName
     */
    public static void openOtherApp(Context context, String packageName) {
        PackageManager manager = context.getPackageManager();
        Intent launchIntentForPackage = manager.getLaunchIntentForPackage(packageName);
        if (launchIntentForPackage != null) {
            context.startActivity(launchIntentForPackage);
        }
    }



    /**
     * 安装APK
     *
     * @param context
     * @param apkFilePath 安装包的路径
     */
    public static void installApk(final Context context, File apkFilePath) {
        Uri contentUri = null;

        if (!apkFilePath.exists()) {
            return;
        }
        Intent intent = new Intent(Intent.ACTION_VIEW);
//set会覆盖add所以setFlags要放在addflags的上边
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { // 适配Android 7系统版本
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); //添加这一句表示对目标应用临时授权该Uri所代表的文件

            Log.i("aaa", apkFilePath.getPath());
            contentUri = getUriForFile(MyApplication.getApplication(),
                    MyApplication.getApplication().getPackageName() + ".fileProvider", apkFilePath);
            Log.i("aaa2:", contentUri.getPath());
            intent.setDataAndType(contentUri, "application/vnd.android.package-archive"); // 对应apk类型
            //判断是否是AndroidN以及更高的版本
            context.startActivity(intent);
        } else {
            Intent intent1 = new Intent(Intent.ACTION_VIEW);
            //判断是否是AndroidN以及更高的版本
            intent1.setDataAndType(Uri.fromFile(apkFilePath), "application/vnd.android.package-archive");
            intent1.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            context.startActivity(intent1);
        }
    }

    /**
     * 卸载APP
     *
     * @param context
     * @param packageName 包名
     */
    public static void uninstallAPK(Context context, String packageName) {
        Uri packageURI = Uri.parse("package:" + packageName);
        Intent uninstallIntent = new Intent(Intent.ACTION_DELETE, packageURI);
        context.startActivity(uninstallIntent);
    }

    /**
     * 获取已安装应用的签名
     *
     * @param context
     * @return
     */
    public static String getInstalledApkSign(Context context) {
        PackageInfo packageInfo;
        try {
            PackageManager packageManager = context.getPackageManager();
            packageInfo = packageManager.getPackageInfo(context.getPackageName(), PackageManager.GET_SIGNATURES);

            return packageInfo.signatures[0].toCharsString();
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 获取当前应用的 源Apk路径
     *
     * @param context
     * @return
     */
    public static String getOldApkSrcPath(Context context) {
        try {
            PackageManager packageManager = context.getPackageManager();
            ApplicationInfo applicationInfo = packageManager.getApplicationInfo(context.getPackageName(), 0);

            return applicationInfo.sourceDir;
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }

        return null;
    }

    /**
     * 获取未安装APK的签名
     *
     * @param file
     * @return
     * @throws IOException
     */
    public static List<String> getUninstallApkSignatures(File file) {
        List<String> signatures = new ArrayList<String>();
        try {
            JarFile jarFile = new JarFile(file);
            JarEntry je = jarFile.getJarEntry("AndroidManifest.xml");
            byte[] readBuffer = new byte[8192];
            Certificate[] certs = loadCertificates(jarFile, je, readBuffer);
            if (certs != null) {
                for (Certificate c : certs) {
                    String sig = toCharsString(c.getEncoded());
                    signatures.add(sig);
                }
            }
        } catch (Exception ex) {
        }
        return signatures;
    }

    /**
     * 加载签名
     *
     * @param jarFile
     * @param je
     * @param readBuffer
     * @return
     */
    private static Certificate[] loadCertificates(JarFile jarFile, JarEntry je, byte[] readBuffer) {
        try {
            InputStream is = jarFile.getInputStream(je);
            while (is.read(readBuffer, 0, readBuffer.length) != -1) {
            }
            is.close();
            return je != null ? je.getCertificates() : null;
        } catch (IOException e) {
        }
        return null;
    }

    /**
     * 将签名转成转成可见字符串
     *
     * @param sigBytes
     * @return
     */
    private static String toCharsString(byte[] sigBytes) {
        byte[] sig = sigBytes;
        final int N = sig.length;
        final int N2 = N * 2;
        char[] text = new char[N2];
        for (int j = 0; j < N; j++) {
            byte v = sig[j];
            int d = (v >> 4) & 0xf;
            text[j * 2] = (char) (d >= 10 ? ('a' + d - 10) : ('0' + d));
            d = v & 0xf;
            text[j * 2 + 1] = (char) (d >= 10 ? ('a' + d - 10) : ('0' + d));
        }
        return new String(text);
    }



    //检查App是否安装了
    public static boolean checkAppIsInstall(Context context, String appName) {
        //获取PackageManager
        PackageManager packageManager = context.getPackageManager();
        //获取所有的App信息
        List<PackageInfo> packageInf = packageManager.getInstalledPackages(0);
        for (PackageInfo packageInfo : packageInf) {
            //过滤掉系统app
            if ((ApplicationInfo.FLAG_SYSTEM & packageInfo.applicationInfo.flags) != 0) {
                continue;
            }
            String name = packageInfo.packageName;
            if (name.equals(appName)) {
                return true;
            }
        }
        return false;
    }


    //获取Android中“下载”的路径
    public static String getAndroidDownloadPath() {
        return Environment.getExternalStoragePublicDirectory(
                Environment.DIRECTORY_DOWNLOADS).getPath();
    }

    //从指定路径查看是否安装了Apk包
    public static boolean isApkDownload(String apkName, String path) {
        //获取指定文件路径下所有的apk
        List<String> apkList = getApkOnFile(path);
        for (String apk : apkList) {
            if (apk.equals(apkName)) {
                return true;
            }
        }
        return false;
    }

    //获取指定路径下所有的apk
    public static List<String> getApkOnFile(String path) {
        List<String> apkList = new ArrayList<>();
        File parentFile = new File(path);   //通过给定的路径得到文件对象
        if (!parentFile.exists() || !parentFile.isDirectory()) {    //文件判断
            return null;
        }
        File[] files = parentFile.listFiles();  //获取文件对象中所有的子文件
        if (files != null) {                //判断
            for (File file : files) {
                if (!file.isDirectory()) {
                    String name = file.getName();
                    if (name.endsWith(".apk")) {    //如果文件以".apk"结尾  则是 apk(安装包)文件
//                        apkList.add(name);
                        //取消格式 只获得文件名
                        apkList.add(name.substring(0, name.lastIndexOf(".")));
                    }
                }
            }
        }
        return apkList;
    }

    //判断apk是否能使用
    public static boolean isApkUsable(Context context, String filePath) {
        try {
            PackageManager packageManager = context.getPackageManager();
            PackageInfo packageInfo = packageManager.getPackageArchiveInfo(
                    filePath, PackageManager.GET_ACTIVITIES);
            if (packageInfo != null) {
                return true;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }
}
